/**
 @Author:          Yotam Hakim
  Create Date:     18/07/2010
  Last Modified:   19/07/2010
 @Brief:           Double Link Data Structure.
**/

#ifndef DLINKLIST_H_INCLUDED
#define DLINKLIST_H_INCLUDED

#include <stdio.h>

typedef struct List_t List;
/*Create new list Data Structure*/
List*   ListNew(void);
/*Destroy list Data Structure ( user keep data)*/
void    ListDel(List*);
/*add new item to end of list*/
int     ListPushH(List*, const  void *itemData);
/*add new item to begining of list*/
int     ListPushT(List*, const  void *itemData);
/*add new items to beginging of list, with many additions - this function is more efficient than repeating ListPushH*/
int     ListPushHM(List* ,size_t elmntsSize,size_t elmntsNumber,const  void *itemsData);
/*add new items to end of list,       with many additions - this function is more efficient than repeating ListPushT*/
int     ListPushTM(List*,size_t elmntsSize,size_t elmntsNumber, const  void *itemsData);
/*get List's Head (first item)*/
void*   ListHead(const List*);
/*get List's Head (Last item)*/
void*   ListTail(const List*);
/*delete List's Head (First item)*/
void    ListPopH(List*);
/*delete List's Tail (Last item)*/
void    ListPopT(List*);
/*Find an element (param) in list. IsMatch function (see  below) compares param to a list element*/
void*   ListFindIf(const List*,int(*IsMatch)(const  void* data,const  void* param),const  void* param);
/*Count number of items in list*/
size_t  ListCount(const List*);
/*Check if list is empty*/
int     ListIsEmpty(const List*);

/*user has to supply  compare function that compares an item ("param") to a list element (_data)*/
typedef int(*IsMatch_t)(const  void* data,const  void* param);
/*
    return value:
    1 for true  (found match)
    0 for false (no    match)

    example : compare two "persons" structures by their age field.

    define :
    int ByAge(void* data,void* param)
    {
        return (int*)(param) == (int*)(data);
    }

    struct person_t
    {
        char *name;
        int age;
    }


    and call ByAge in some  function :

    struct person_t yosi,rita;
    IsMatch_t Func = ByAge;
    strcpy(yosi.name, "Yosi");      strcpy(rita.name, "Rita");
    yosi.age = 55;                  rita.age = 54;

    bool = ByAge(rita,yosi) ;   //which in this case is false --> bool = 0;

    // in DLlist context:
    List* list;
    ListPushH(list, void* (yosi)); //inserting yosi to list
    //check if rita's age is found in list
    ListFindIf(list,ByAge,(void*)(rita)));

*/
#endif /* DLINKLIST_H_INCLUDED*/
